www.gusucode.com > VC++ 简易二维平面CAD绘图程序-源码程序 > VC++ 简易二维平面CAD绘图程序-源码程序/code/CAD/ManagerTool.cpp

    //Download by http://www.NewXing.com
// ManagerTool.cpp: implementation of the CManagerTool class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ManagerTool.h"
#include "LineTool.h"
#include "RectangleTool.h"
#include "CircleTool.h"
#include "WinApp.h"
#include "MoveLine.h"
#include "MoveCircle.h"
#include "MoveRectangle.h"
#include "CopyLine.h"
#include "CopyCircle.h"
#include "CopyRectangle.h"
#include "MirrorLine.h"
#include "MirrorCircle.h"

extern CWinApp g_theApp;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CManagerTool::CManagerTool()
{
	//初始化成员变量
	m_pCurrentTool = NULL;
	pMoveShape     = NULL;
	pCopyShape     = NULL;
	pCurShape      = NULL;
	pShape         = NULL;
	LBDown         = 0;
	copyFlag       = 0;	
	MirrorFlag     = 0;
	MouseFlag      = NoHit;
}

CManagerTool::~CManagerTool()
{

}

//功能:设置当前绘图工具
void CManagerTool::SetCurActiveTool(unsigned int ID)
{
	//改变当前工具状态前,初始化为无状态
	if(m_pCurrentTool != NULL)
	{
		delete m_pCurrentTool;
		m_pCurrentTool = NULL;
	}

	switch (ID)
	{	
	case ID_DRAW_LINE:
		m_pCurrentTool = new CLineTool;
		break;
	case ID_DRAW_RECTANGLE:
		m_pCurrentTool = new CRectangleTool;
		break;
	case ID_DRAW_C2PT:
		m_pCurrentTool = new CCircleTool;
		break;
	}
	
}

//功能:绘图
void CManagerTool::DrawObject(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if( m_pCurrentTool == NULL ) return ;

	int   nFlag  = wParam;
	int   NCFlag = 0;             //非显示区域消息标记
	POINT ptPos;

	ptPos.x = LOWORD(lParam);  
	ptPos.y = HIWORD(lParam);  	

	switch(message)
	{		
		case WM_MOUSEMOVE: 
			{
				m_pCurrentTool->OnMouseMove(hWnd,nFlag,ptPos);			 
			}break;
		case WM_LBUTTONDOWN :
			{
				m_pCurrentTool->OnLButtonDown(hWnd,nFlag,ptPos);			 
			}break;
		case WM_RBUTTONDOWN :
			{
				m_pCurrentTool->OnRButtonDown(hWnd,nFlag,ptPos);			 
			}break;
		case WM_NCMOUSEMOVE:
			{
				NCFlag = 1;
			}
		case WM_SETCURSOR :
			{		
				UINT uCURID = IDC_CURSOR2;
				//当鼠标移至非显示区域
				if (NCFlag == 1)
					uCURID = IDC_CURSOR1;
				HCURSOR hCur = ::LoadCursor(g_theApp.GetInst(),MAKEINTRESOURCE(uCURID));					
				::SetCursor(hCur);			 
			}
	}
}


//功能:编辑图形
BOOL CManagerTool::EditObject(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int       redraw = 0;                          //刷新标记
	POINT     ptPos;	
	CDataBase *pDataBase = &(g_theApp.m_DataBase);	
	HCURSOR   hCur = NULL;

	ptPos.x = LOWORD(lParam);  
	ptPos.y = HIWORD(lParam);  

	switch(message)
	{		
		case WM_SETCURSOR:
			{
				UINT uCURID = IDC_CURSOR1;
				//上线
				if(pShape != NULL)				
				{
					uCURID = IDC_CURSOR3;
				}	
				
				HCURSOR hCur = ::LoadCursor(g_theApp.GetInst(),(LPCTSTR)uCURID);
				::SetCursor(hCur);
			}break;
		case WM_LBUTTONUP :
			{	
				if (pCurShape != NULL && LBDown == 1 && copyFlag == 1)
				{
					pDataBase->m_ArrayShape.Add(pCurShape);						
				}
				
				LBDown = 0;	
				redraw = 1;

				//释放非窗口鼠标消息
				ReleaseCapture () ;
			}break;
		case WM_LBUTTONDOWN :
			{
				if (pShape != NULL)				
				{
					//更新图形选择
					if (pCurShape != NULL && pCurShape != pShape)
					{
						pCurShape->isPick = FALSE;					
					}

					LBDown    = 1;				
					pCurShape = pShape;	
					pCurShape->isPick = TRUE;				
					ptPrePos  = ptPos;
					
					//拾取
					HCURSOR hCur = ::LoadCursor(g_theApp.GetInst(),(LPCTSTR)IDC_CURSOR4);
					::SetCursor(hCur);
				}
				else
				{
					pCurShape = pShape;	
				}

				//拦截鼠标在窗口外的消息
				SetCapture (hWnd) ;	
			}break;
		case WM_MOUSEMOVE: 
			{
				//
				copyFlag = 0;
				
				if ( (wParam & MK_LBUTTON) && pCurShape != NULL && pCurShape->isPick == TRUE)
				{
					//移动图形					
					HDC hdc = GetDC(hWnd);
					SetMoveShape(pCurShape);

					//复制图形
					if(wParam & MK_CONTROL) 
					{
						HCURSOR hCur = ::LoadCursor(g_theApp.GetInst(),(LPCTSTR)IDC_CURSOR5);
						::SetCursor(hCur);
						copyFlag = 1;
						SetCopyShape(pCurShape);
						pCurShape = pCopyShape->Copy();
						SetMoveShape(pCurShape);						
					}	
					
					pMoveShape->Move(hdc,(ptPos.x - ptPrePos.x),(ptPos.y - ptPrePos.y));
					
					ReleaseDC(hWnd,hdc);				
					ptPrePos = ptPos;
				}				
				else
				{
					int i = 0;
					for(;i < pDataBase->m_ArrayShape.GetArraySize();i++)
					{					
						if (pDataBase->m_ArrayShape[i]->pick(ptPos) == TRUE)
						{	
							//唯一选择判定											
							pShape = pDataBase->m_ArrayShape[i];						
							break;
						}
						else
						{
							pDataBase->m_ArrayShape[i]->isPick = FALSE;					
						}
					}
					//没有可选图形
					if (i == pDataBase->m_ArrayShape.GetArraySize()) pShape = NULL;								
				}								
			}break;
		case WM_RBUTTONDOWN :
			{	
				if (pCurShape != NULL)
				{						
					pCurShape = NULL;
					redraw = 1;
				}
			}
	}
	return redraw;
}

//功能:响应当前菜单编辑行为
void CManagerTool::OnCurMenuAction(HWND hWnd,unsigned int ID)
{
	CDataBase *pDataBase = &(g_theApp.m_DataBase);

	if (pCurShape == NULL)
	{
		MessageBox(hWnd,"Please choose a object first!","prompt",MB_OK);
	}
	else
	{
		switch (ID)
		{
		case ID_EDIT_COPY:
			{	
				//令粘贴功能可选
				HMENU hMenu = ::GetMenu( hWnd);
				::EnableMenuItem(hMenu,ID_EDIT_PASTE,MF_ENABLED);				
			}
			break;
		case ID_EDIT_MIRROR:
			{			
				MirrorFlag = 1;				
			}
			break;	
		case ID_EDIT_PASTE:
			{					
				HDC hdc = GetDC(hWnd);

				SetCopyShape(pCurShape);
				pCurShape = pCopyShape->Copy();

				SetMoveShape(pCurShape);
				pMoveShape->Move(hdc,Offset,Offset);

				pDataBase->m_ArrayShape.Add(pCurShape);				

				ReleaseDC(hWnd,hdc);

				//令粘贴功能不可选
				HMENU hMenu = ::GetMenu( hWnd );
				::EnableMenuItem(hMenu,ID_EDIT_PASTE,MF_GRAYED);			
				InvalidateRect(hWnd,NULL,TRUE);					
			}
			break;
		case ID_EDIT_DELETE:
			{				
				for (int i=0;i<pDataBase->m_ArrayShape.GetArraySize();i++)
				{
					if(pDataBase->m_ArrayShape[i] == pCurShape)
					{
						pDataBase->m_ArrayShape.RemoveAt(i);
						pCurShape = NULL;

						//令粘贴功能不可选
						HMENU hMenu = ::GetMenu( hWnd );
						::EnableMenuItem(hMenu,ID_EDIT_PASTE,MF_GRAYED);
						InvalidateRect(hWnd,NULL,TRUE);
					}
				}
				
			}		
		}
	}
}

//功能:设置当前移动图形
void CManagerTool::SetMoveShape(CShape *pShape)
{	
	if (pMoveShape != NULL)
	{
		delete pMoveShape;
		pMoveShape = NULL;
	}
	if (pShape != NULL)	
	{
		if (strcmp(pShape->m_className,"CLine") == 0)
			pMoveShape = new CMoveLine(pShape);
		if (strcmp(pShape->m_className,"CCircle") == 0)
			pMoveShape = new CMoveCircle(pShape);
		if (strcmp(pShape->m_className,"CRectangle") == 0)
			pMoveShape = new CMoveRectangle(pShape);
	}	
}

//功能:设置当前复制图形
void CManagerTool::SetCopyShape(CShape *pShape)
{	
	if (pMoveShape != NULL)
	{
		delete pCopyShape;
		pCopyShape = NULL;
	}
	if (pShape != NULL)	
	{
		if (strcmp(pShape->m_className,"CLine") == 0)
			pCopyShape = new CCopyLine(pShape);
		if (strcmp(pShape->m_className,"CCircle") == 0)
			pCopyShape = new CCopyCircle(pShape);
		if (strcmp(pShape->m_className,"CRectangle") == 0)
			pCopyShape = new CCopyRectangle(pShape);
	}
}


//功能:设置当前镜像图形
void CManagerTool::SetMirrorShape(CShape *pShape)
{	
	if (pMirrorShape != NULL)
	{
		delete pMirrorShape;
		pMirrorShape = NULL;
	}
	if (pShape != NULL)	
	{
		if (strcmp(pShape->m_className,"CLine") == 0)
			pMirrorShape = new CMirrorLine(pShape);
		if (strcmp(pShape->m_className,"CCircle") == 0)
			pMirrorShape = new CMirrorCircle(pShape);
		if (strcmp(pShape->m_className,"CRectangle") == 0)
			pMirrorShape = NULL;
	}
}



BOOL CManagerTool::MirrorObject(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	BOOL      result = TRUE;                          
	POINT     ptPos;	
	CDataBase *pDataBase = &(g_theApp.m_DataBase);	

	ptPos.x = LOWORD(lParam);  
	ptPos.y = HIWORD(lParam);  

	switch(message)
	{
	case WM_LBUTTONDOWN :
		{
			if (MouseFlag == NoHit)
			{
				MouseFlag  = Hit;
				ptBeginPos = ptPrePos = ptPos;				
			}
			else
			{
				SetCopyShape(pCurShape);
				pCurShape = pCopyShape->Copy();
				pCurShape->m_ptFirstPos  = pMirrorShape->MirrorBeginPos;
				pCurShape->m_ptSecondPos = pMirrorShape->MirrorEndPos;
				pDataBase->m_ArrayShape.Add(pCurShape);	
				MouseFlag = NoHit;
				result    = FALSE;
			}
			
		}break;
	case WM_MOUSEMOVE:
		{
			if (MouseFlag == Hit)
			{
				HDC hdc = GetDC(hWnd);

				SetMirrorShape(pCurShape);

				if (pMirrorShape == NULL)
				{
					MouseFlag = NoHit;
					return FALSE;
				}

				int nOldMode = ::SetROP2(hdc,R2_XORPEN);
				HPEN hPen    = ::CreatePen(0,1,RGB(255,255,128)^ GetBkColor(hdc) );

				HPEN hOldPen = (HPEN)::SelectObject(hdc,hPen);

				//擦去前一次线段
				CDraw::DrawLine(hdc,ptBeginPos,ptPrePos);

				//画出这一次线段		
				CDraw::DrawLine(hdc,ptBeginPos,ptPos);	
				
				pMirrorShape->Mirror(hdc,ptBeginPos,ptPrePos,ptPos);
				
				::SetROP2(hdc,nOldMode);
				::SelectObject(hdc,hOldPen);
				::DeleteObject(hPen);
				::ReleaseDC(hWnd,hdc);
				
				ptPrePos = ptPos;
			}
		}break;
	case WM_RBUTTONDOWN :
		{
			if (MouseFlag == Hit)
				MouseFlag = NoHit;
			result    = FALSE;	
		}break;
	}
					
	return result;		
}